//
//  Room.swift
//  
//
//  Created by Jiang Chencheng on 2024/9/3.
//

import Vapor
import Fluent
import struct Foundation.UUID

enum PetType: String, Codable {
    case cat
    case dog
}

enum PlantType: String, Codable {
    case tree
    case flower
}


enum PlantStage: String, Codable {
    
    case baby
    
}


/// 宠物
final class Pet: Fields, @unchecked Sendable {
    
    @Field(key: "name")
    var name: String
    
    @Enum(key: "type")
    var type: PetType
    
    
    @Enum(key: "mood")
    var mood: Mood
    
    init() {
        self.name = ""
        self.type = .cat
        self.mood = .default
    }
}

/// 植物
final class Plant: Fields, @unchecked Sendable {
    
    @Field(key: "name")
    var name: String
    
    @Enum(key: "type")
    var type: PlantType
    
    @Enum(key: "stage")
    var stage: PlantStage

    
    init() {
        self.name = ""
        self.type = .tree
        self.stage = .baby
    }
}

final class Room: Model, @unchecked Sendable {
    
    static let schema = "room"
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: "name")
    var name: String

    @Parent(key: "user_id_owner")
    var owner: User
    
    @OptionalParent(key: "user_id_partner")
    var partner: User?
    
    @Group(key: "pet")
    var pet: Pet
    
    @Group(key: "plant")
    var plant: Plant
    
    @Field(key: "star")
    var star: UInt
    
    @Field(key: "hot")
    var hot: UInt
    
    @Field(key: "energy")
    var energy: UInt
    
    @Children(for: \.$room)
    var photos: [Photo]
    
    @Children(for: \.$room)
    var diaries: [Diary]

    @Timestamp(key: "created_at", on: .create)
    var createdAt: Date?

    @Timestamp(key: "updated_at", on: .update)
    var updatedAt: Date?
    
    @Timestamp(key: "deleted_at", on: .delete)
    var deletedAt: Date?
    
    init() { 
        self.name = ""
        self.star = 0
        self.hot = 0
        self.energy = 0
    }
    
    init(id: UUID? = nil, ownerID: UUID, partnerID: UUID? = nil) throws {
        self.name = ""
        self.star = 0
        self.hot = 0
        self.energy = 0
        self.$owner.id = ownerID
        self.$partner.id = partnerID
    }
    
    func toDTO() -> RoomDTO {
        .init(
            id: self.id,
            name: self.name,
            pet: self.pet,
            star: self.star,
            hot: self.hot,
            energy: self.energy
        )
    }
    
    static func query(on db: any Database, userID: UUID) async throws -> Room {
        let room = try await Room
            .query(on: db)
            .group(.or) {
                $0
                .filter(\.$owner.$id ==  userID)
                .filter(\.$partner.$id ==  userID)
            }
            .first()
        
        guard let room else {
            throw BizError.roomNotFound
        }
        
        return room
    }

}


